import { defineAsyncComponent, h } from "vue";
import Error from "../components/Error.vue";
import Loading from "../components/Loading.vue";
import "nprogress/nprogress.css";
import NProgress from "nprogress";
NProgress.configure({ // 进度条都是假的，因为浏览器加载了多少浏览器是不会给你的
  trickleSpeed: 50,
  showSpinner: false,
});

export function delay(duration) {
  if (!duration) {
    duration = random(1000, 5000);
  }

  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, duration);
  });
}

export function random(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

// 得到一个异步页面，加载一次，后面有缓存
export function getAsyncPage(path) {
  return defineAsyncComponent({
    loader: async () => {
      NProgress.start();
      await delay();
      const comp = await import(path);
      NProgress.done();
      return comp;
    },
    loadingComponent: Loading, // 当promise在pending状态时，将显示这里的组件
  });
}

// 得到一个异步组件，加载一次，后面有缓存，但是如果出错了，会重复加载
export function getAsyncComponent(path) {
  return defineAsyncComponent({
    loader: async () => { // 如果只有loader，可以简写，直接传递一个函数，这里的配置项和vue2有一点区别
      await delay();
      if (Math.random() < 0.5) {
        throw new TypeError(); // promise reject，显示errorComponent
      }
      return import(path);
    },
    loadingComponent: Loading, // 当promise在pending状态时，将显示这里的组件
    errorComponent: { // 当promise reject时，将显示这里的组件，如果没有配置这个，将一直显示loadingComponent
      render() {// render函数没有h参数了，因为创建虚拟节点不一定在vue组件中，vue3的h和vue2的h用法不一样
        return h(Error, "出错了！！！"); // 元素内容是 出错了！！！
      },
    },
    // errorComponent: Error // 这样写无法传递插槽，所以改用上面的写法
  });
}

